package com.amex.uam.tasks;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import com.amex.uam.pojo.MSLogin;
import com.amex.uam.pojo.SecurityGroupBean;
import com.google.gson.Gson;
import com.microstrategy.web.beans.BeanFactory;
import com.microstrategy.web.beans.UserEntitiesBean;
import com.microstrategy.web.beans.UserEntityBean;
import com.microstrategy.web.beans.UserGroupBean;
import com.microstrategy.web.beans.WebBeanException;
import com.microstrategy.web.objects.WebFolder;
import com.microstrategy.web.objects.WebIServerSession;
import com.microstrategy.web.objects.WebObjectInfo;
import com.microstrategy.web.objects.WebObjectSource;
import com.microstrategy.web.objects.WebObjectsException;
import com.microstrategy.web.objects.WebObjectsFactory;
import com.microstrategy.web.objects.WebSearch;
import com.microstrategy.web.objects.admin.users.WebUser;
import com.microstrategy.web.objects.admin.users.WebUserGroup;
import com.microstrategy.webapi.EnumDSSXMLApplicationType;
import com.microstrategy.webapi.EnumDSSXMLObjectSubTypes;
import com.microstrategy.webapi.EnumDSSXMLSearchDomain;
import com.microstrategy.webapi.EnumDSSXMLSearchFlags;

public class MDHelper {

	public static enum BaseGroup {
		
		MARC ("MARC"), 
		Privileges ("Privileges"); 
		
		private String name;
		private BaseGroup(String name){
			this.name = name;
		}
		public String getName() {
			return name;
		}
	}
	
	public static SecurityGroupBean getGroups(BaseGroup group, WebIServerSession session) {
		return getGroups(group.getName(), session);
	}
	
	public static SecurityGroupBean getGroups(String groupName, WebIServerSession session) {
		WebObjectSource wos = session.getFactory().getObjectSource();
		WebSearch search = wos.getNewSearchObject();
		search.setSearchFlags(search.getSearchFlags() & ~EnumDSSXMLSearchFlags.DssXmlSearchUsesRecursive );  
		search.setAsync(false );  
		search.types().add(EnumDSSXMLObjectSubTypes.DssXmlSubTypeUserGroup);
		search.setDomain(EnumDSSXMLSearchDomain.DssXmlSearchConfigurationAndAllProjects );
		
		try {
			search.submit();
			WebFolder results = search.getResults();
			String baseId = null; 
			for (int i = 0; i < results.size(); i++) {
				WebObjectInfo obj = results.get(i);
				if (groupName.equalsIgnoreCase(obj.getName())) {
					baseId = obj.getID();
				}
			}
			
			return getGroups(baseId, session, 0);
		
		} catch (WebObjectsException e) {
			e.printStackTrace();
		}
		
		
		return null;
	}
	
	public static SecurityGroupBean getGroups(String baseId, WebIServerSession session, int level) {
		
		
		UserGroupBean usrGrp = (UserGroupBean) BeanFactory.getInstance().newBean("UserGroupBean");
		usrGrp.setSessionInfo(session);
		usrGrp.setObjectID(baseId);
		
		SecurityGroupBean scyGrpBean = new SecurityGroupBean();
		
		try {
			// debug output
			//System.out.println(indent(level) + usrGrp.getObjectName());
			
			scyGrpBean.setGroupName(usrGrp.getObjectName());
			scyGrpBean.setGroupID(usrGrp.getObjectID());
			scyGrpBean.setGroup(usrGrp.isGroup());
			
			UserEntitiesBean children = usrGrp.getChildren();
			for (int i = 0; i < children.size(); i++) {
				UserEntityBean entity = children.get(i);
				if (entity.isGroup()) {
					
					SecurityGroupBean chd = getGroups(entity.getObjectID(), session, level + 1);
					scyGrpBean.addChild(chd);
					
				} /*else if (!scyGrpBean.isContains()) {
					// find user's group
					if (entity.getObjectID().equals(session.getUserInfo().getID())) {
						scyGrpBean.setContains(true);
						
						// debug output
						//System.out.println(indent(level + 1) + " **contains: " + entity.getObjectName());
						
					}
					
				}*/
				
			}
			return scyGrpBean;
		} catch (WebBeanException e) {
			e.printStackTrace();
		}
		
		return null;
	}
	private static String indent(int level) {
		StringBuffer buff = new StringBuffer();
		for (int i = 0; i < level; i++) {
			buff.append('\t');
		}
		return buff.toString();
	}
	
	public static WebIServerSession getAdminSession(MSLogin user){
        
        WebObjectsFactory objectFactory = WebObjectsFactory.getInstance();
		WebIServerSession sessionInfo = objectFactory.getIServerSession();
		sessionInfo.setServerName(user.getServerName());
		sessionInfo.setLogin(user.getUsername());
		sessionInfo.setPassword(user.getPassword());
		sessionInfo.setApplicationType(EnumDSSXMLApplicationType.DssXmlApplicationCustomApp);
    	return sessionInfo;
    }
	
	
	public static List<SecurityGroupBean> getUserGroups(String userName, WebIServerSession session) {
		
		WebObjectSource source = session.getFactory().getObjectSource();
		// Set up search objects
		WebSearch userSearch = source.getNewSearchObject();
		
		userSearch.setNamePattern(userName);
		userSearch.setAsync(false);
		userSearch.types().add(EnumDSSXMLObjectSubTypes.DssXmlSubTypeUser);
		userSearch.setDomain(EnumDSSXMLSearchDomain.DssXmlSearchConfigurationAndAllProjects);
		
		List<SecurityGroupBean> list = new ArrayList<SecurityGroupBean>();
		try {
			WebUser user = (WebUser) performSearch(userSearch);
			if (user != null) {
				System.out.println(user.getAncestorGroups().length);
				user.populate();
				Enumeration elements = user.getParents().elements();
				// System.out.println(parents.size());
				while(elements.hasMoreElements())
				{
					Object obj = elements.nextElement();
					if (obj instanceof WebUserGroup) {
						WebUserGroup group = (WebUserGroup)obj; 
						// System.out.println(group.getID() + " " + group.getName());
						SecurityGroupBean bean = new SecurityGroupBean();
						bean.setGroup(true);
						bean.setGroupName(group.getName());
						bean.setGroupID(group.getID());
						list.add(bean);
					}
				}
				
				// Get all groups
				/*WebUserGroup[] groups = user.getAncestorGroups();
				for (int i = 0; i < groups.length; i++) {
					System.out.println(groups[i]);
				}*/
			}
		} catch (WebObjectsException e) {
			e.printStackTrace();
		}
		return list;
	}

	public static Object performSearch(WebSearch search) {
		try {
			search.submit();
			WebFolder folder = search.getResults();
			if (folder.size() > 0) {
				if (folder.size() == 1) {
					return folder.get(0);
				} else {
					System.out.println("Search returns more than 1 object, returning first object");
					return folder.get(0);
				}
			}
		} catch (WebObjectsException ex) {
			System.out.println("Error performing search: " + ex.getMessage());
		}
		return null;
	}
	public static List<SecurityGroupBean> getUserGroups(WebIServerSession session) {
		List<SecurityGroupBean> list = new ArrayList<SecurityGroupBean>();
		if (session != null) {
			
			try {
				WebUser user = (WebUser)session.getUserInfo();
				user.populate();
				Enumeration elements = user.getParents().elements();
				while(elements.hasMoreElements())
				{
					Object obj = elements.nextElement();
					if (obj instanceof WebUserGroup) {
						WebUserGroup group = (WebUserGroup)obj; 
						SecurityGroupBean bean = new SecurityGroupBean();
						bean.setGroup(true);
						bean.setGroupName(group.getName());
						bean.setGroupID(group.getID());
						list.add(bean);
					}
				}
			} catch (WebObjectsException e) {
				e.printStackTrace();
			}
		}
		return list;
	}
	public static void main(String[] args) throws Throwable {
		MSLogin user = new MSLogin();
		user.setServerName("localhost");
		user.setUsername("Administrator");
		user.setPassword("");
		//user.setProducts("MARC, ICARD, Dashboard");
		WebIServerSession session = getAdminSession(user);
		
		//SecurityGroupBean marcGrp = getGroups(BaseGroup.MARC, session);
		
		Gson gson = new Gson();
		//System.out.println(gson.toJson(marcGrp));
		
//    	List<List<SecurityGroupBean>> list = MDServiceHandler.getGroups(user);
//    	System.out.println(Utils.toJSON(list));
	}
}
